#pragma once

#include "LeDocumentObject_global.h"

#include <QAbstractItemModel>

#include "IDocumentObjectListener.h"

namespace LDO
{

    class Document;
    class IDocumentObject;

    class DocumentObjectTreeModelPrivate;
    class LDO_EXPORT DocumentObjectTreeModel : public QAbstractItemModel, public IDocumentObjectListener
    {
        Q_OBJECT
        Q_DECLARE_PRIVATE(DocumentObjectTreeModel)
        QScopedPointer<DocumentObjectTreeModelPrivate> const d_ptr;

    public:
        enum
        {
            NameColumn,
            ColumnCount
        };

        explicit DocumentObjectTreeModel(QObject *parent = 0);
        ~DocumentObjectTreeModel();

        void setRootObject(Document *document, IDocumentObject *object);
        IDocumentObject *rootObject() const;
        IDocumentObject *documentObject(const QModelIndex &index) const;

        QModelIndex index(const IDocumentObject *object) const;

        // QAbstractItemModel Interface
    public:
        QModelIndex index(int row, int column,
                          const QModelIndex &parent = QModelIndex()) const override;
        QModelIndex parent(const QModelIndex &index) const override;
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        int columnCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override;
        virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
        virtual Qt::ItemFlags flags(const QModelIndex &index) const override;

        //
        // FIXME: All the below have to be moved to DocumentObjectTreeModelPrivate
        //

        // IDocumentObjectListener interface
    public:
        virtual void documentObjectAboutToBeInserted(IDocumentObject *parent, IDocumentObject *child, int index) override;
        virtual void documentObjectInserted(IDocumentObject *parent, IDocumentObject *child, int index) override;
        virtual void documentObjectAboutToBeRemoved(IDocumentObject *parent, IDocumentObject *child, int index) override;
        virtual void documentObjectRemoved(IDocumentObject *parent, IDocumentObject *child, int index) override;
        virtual void documentObjectAboutToChangeProperty(const IDocumentObject *object, const QString &name, const QVariant &oldValue) override;
        virtual void documentObjectPropertyChanged(const IDocumentObject *object, const QString &name, const QVariant &newValue) override;
        // helpers
        void startListeningRecursive(IDocumentObject *object);
        void stopListeningRecursive(IDocumentObject *object);
    };

}
